home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SeperateUnderlineShape.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains routines to seperate text and glyph shapes that contain
- underlines in their text face into two shapes, one with just the text
- and the other with just the underline, converted into a path shape.
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1992-1997 by Apple Computer, Inc., all rights reserved.
- */
-
-
- #include "GXToPSBuildConfig.h"
- #include <GXGraphics.h>
- #include "GXGraphicsPriv.h"
- #include <GXEnvironment.h>
- #include "GXToPostScript.h"
- #include "IOUtilities.h"
- #include "RDUtil.h"
- #include "FontHandler.h"
- #include "PublicPostScriptIE.h"
- #include "private.h"
- #include "PSIEResources.h"
- #include "GXErrors.h"
- #include "ShapeUtilities.h"
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
-
- #ifdef DONTUSECHRISCODE
- //<FF>
- /*********************************************
-
- Function: SeperateUnderlineShape:
-
- Routine to generate two shapes from a text
- or glyph shape. One shape will be the original
- shape, and the second one will be a copy of it
- with only the underline layers in the text face…
- This shape will be converted to a path.
-
- Any underline layers that are white layers will
- be converted to paths and combined with the clip
- of the source shape.
-
- The provided shape will be converted to a
- picture which will contain both shapes.
-
- *********************************************/
- OSErr _SeperateUnderlineShape(TIEGlobalsHdl hIEGlobals, gxShape theShape)
- {
- OSErr status, saveStatus;
- gxShape underlineShape;
- long nStyles; // Number of styles in the glyph shape.
- #if 0
- short shortNstyles; // GetLayout likes shorts.
- #endif
- Handle hWorkSpace; // the workspace.
- gxTextFace *theFace; // Pointer to a text face.
- gxFaceLayer *theLayer; // Pointer to a layer.
- long nLayers; // Numbe of layers in the style.
- gxStyle *theStyles; // array of styles for the shape.
- short *theRuns; // The style runs (required for calling SetGlhyphs)
- long nChars; // Number of characters (required for calling setGlyphs)
- gxStyle *newStyles; // array of new styles for the underline shape.
- gxStyle *pStyle; // Pointer into array of new styles.
- gxStyle aStyle; // a particular style from the shape.
- gxStyle aNewStyle; // a particular new style for the new shape.
- gxShapeType theType;
- long i, j;
- long faceSize; // size of the text face
-
- char faceData[ sizeof(gxTextFace) + sizeof(gxFaceLayer) ];
-
- gxTextFace *noDrawFace; // text face that will cause no drawing.
-
- noDrawFace = (gxTextFace*)faceData;
-
- theType = GXGetShapeType(theShape);
- check( (theType == gxTextType) || (theType == gxGlyphType) || (theType == gxLayoutType));
-
- aStyle = GXGetShapeStyle(theShape); // get the shape's main style, we may need it.
-
- underlineShape = GXCopyToShape(nil, theShape);
-
- noDrawFace->faceLayers = 1;
- ResetMapping(&noDrawFace->advanceMapping);
- noDrawFace->faceLayer[0].outlineFill = gxNoFill;
- noDrawFace->faceLayer[0].flags = 0x0000;
- noDrawFace->faceLayer[0].outlineStyle = nil;
- noDrawFace->faceLayer[0].outlineTransform = nil;
- noDrawFace->faceLayer[0].boldOutset.x = 0;
- noDrawFace->faceLayer[0].boldOutset.y = 0;
-
-
- if (theType == gxTextType) {
-
- nStyles = 1;
- theStyles = &aStyle;
- newStyles = &aNewStyle;
-
- } else {
-
- if (theType == gxGlyphType) {
-
- GXGetGlyphs(theShape, &nChars, nil, nil, nil, nil, &nStyles, nil, nil);
-
- } else {
- #if 0
- GXGetLayout(theShape, nil, &shortNstyles, nil, nil, nil, nil, nil, nil, nil);
- nStyles = shortNstyles;
- #else
- GXGetLayout(theShape, nil, &nStyles, nil, nil, nil, nil, nil, nil, nil);
- #endif
- }//end if
-
- /** Enough space for 2 of each style and the runs **/
-
- status = PSSetWorkSpaceSize(hIEGlobals, 2 * nStyles * sizeof(gxStyle) + nStyles * sizeof(short));
- nrequire(status, failed_SrcStyleSpace);
-
- hWorkSpace = (*hIEGlobals)->hWorkSpace;
- HLock(hWorkSpace);
- theRuns = (short*)*hWorkSpace;
- theStyles = (gxStyle*)(*hWorkSpace + nStyles * sizeof(short));
- newStyles = theStyles + nStyles;
-
- if (theType == gxGlyphType)
- GXGetGlyphs(theShape, nil, nil, nil, nil, nil, nil, theRuns, theStyles);
- else
- GXGetLayout(theShape, nil, nil, theRuns, theStyles, nil, nil, nil, nil, nil);
-
- }//end if
-
-
- /* Now loop through all styles, generate new ones with just underline layers */
- pStyle = newStyles;
- for (i = 0; i < nStyles; i++) {
-
- if (*theStyles == nil)
- *theStyles = aStyle;
-
- *pStyle = GXCopyToStyle(nil, *theStyles); // make a copy of the style.
-
- nLayers = GXGetStyleFace(*theStyles, nil);
-
- if (nLayers >= 0) { // as long as there was a face, even with no layers…
-
- faceSize = sizeof(gxTextFace) + nLayers * sizeof(gxFaceLayer);
- nrequire(status = PSSetWorkSpaceSize(hIEGlobals, faceSize), failed_FaceSpace);
-
- theFace = (gxTextFace*)(*(*hIEGlobals)->hWorkSpace); // Hope gx graphics calls don't move memory.
-
- GXGetStyleFace(*theStyles, theFace);
-
-
- /** Make a new text face that has all of the non-underline layers set to noFill **/
-
- if (nLayers > 0) {
-
- theLayer = theFace->faceLayer;
-
- for (j = nLayers - 1; j >= 0; --j) {
-
- /******
- Leave glyph clip layers with their original fill, necessary for converting
- underline to a path, so underline gets clipped to glyphs.
- ******/
- if (!(theLayer->flags & kUnderlineCheckMask) || !(theLayer->flags & gxClipLayer))
- theLayer->outlineFill = gxNoFill;
-
- ++theLayer;
-
- }//end for
-
-
- } else if (nLayers == 0) { // Make a non drawing layer.
-
- /**
- We know we have enough workspace for at least one layer since this block is
- only executed if nLayers > 0, so construct a no drawing layer and the
- sizeof(gxTextFace) has room for at least one layer because of anyNumber constant.
- ***/
- theFace->faceLayers = 1;
- theFace->faceLayer[0].outlineFill = gxNoFill;
- theFace->faceLayer[0].outlineStyle = nil;
- theFace->faceLayer[0].outlineTransform = nil;
- theFace->faceLayer[0].flags = 0;
- theFace->faceLayer[0].boldOutset.x = 0;
- theFace->faceLayer[0].boldOutset.y = 0;
-
- }//end if
-
- GXSetStyleFace(*pStyle, theFace);
-
- } else { // the style had no face, do something to make it not draw.
-
- GXSetStyleFace(*pStyle, noDrawFace);
-
- }//end if
-
- if (nLayers >= 0) { //if we allocated workspace for face, get rid of it.
-
- /** First dispose of styles and transforms in the face **/
- theLayer = theFace->faceLayer;
- for (j = 0; j < nLayers; ++j) {
-
- if (theLayer->outlineStyle != nil)
- GXDisposeStyle (theLayer->outlineStyle);
-
- if (theLayer->outlineTransform != nil)
- GXDisposeTransform(theLayer->outlineTransform);
-
- ++theLayer;
-
- }//end for
-
- status = PSReleaseWorkSpace(hIEGlobals); // release workspace for this style's face.
- nrequire(status, failed_FaceSpace);
-
- }//end if
-
- ++theStyles;
- ++pStyle;
-
- }//end for
-
- /** Now we have an array of new styles that contain only layers in the face that don't draw **/
-
- if (theType == gxTextType) {
-
- GXSetShapeStyle(underlineShape, aNewStyle);
- GXDisposeStyle(aNewStyle);
-
- } else {
-
- if (theType == gxGlyphType)
- GXSetGlyphs(underlineShape, nChars, nil, nil, nil, nil, theRuns, newStyles);
- else
- GXSetLayout(underlineShape, 0, nil, nil, nStyles, theRuns, newStyles, nil, nil, nil, nil, nil);
-
- pStyle = newStyles;
- for ( i = 0; i < nStyles; ++i)
- GXDisposeStyle(*pStyle++);
-
- }//end if
-
-
- /** Now generate the 2 shape picture, one shape the original, 2nd is path version of underlines **/
-
- GXSetShapeType(underlineShape, gxPathType);
-
- #if DEBUGLEVEL > 1
- //GXMoveShape(underlineShape, ff(100), ff(100)); // So we can see shape by itself.
- #endif
-
- GXSetShapeType(theShape, gxPictureType);
- GXSetPictureParts(theShape, 0, 0, 1, &underlineShape, nil, nil, nil);
-
- status = GXGetGraphicsError(nil);
- ncheck(status);
-
- failed_FaceSpace:
-
- saveStatus = PSReleaseWorkSpace(hIEGlobals); // release workspace used for source styles.
- if (status == noErr)
- status = saveStatus;
-
- failed_SrcStyleSpace:
-
- return(status);
-
- }//SeperateUnderlineShape
-
- #else
-
-
- /*********************************************
-
- Function: SeperateUnderlineShape:
-
- Routine to generate two shapes from a text
- layout, or glyph shape. One shape will be the original
- shape, and the second one will be a picture
- containing the underlines.
-
- *********************************************/
- OSErr _SeperateUnderlineShape(TIEGlobalsHdl hIEGlobals, gxShape theShape)
- {
- #pragma unused(hIEGlobals)
-
- OSErr status = noErr;
- gxShape underlineShape;
- gxShapeType theType;
- gxShape shapeCopy;
-
- theType = GXGetShapeType(theShape);
- if ( (theType == gxTextType) || (theType == gxGlyphType) || (theType == gxLayoutType) ) {
-
- /* Get the picture full of underline shapes */
-
- if ( (theType == gxTextType) || (theType == gxGlyphType) ) {
-
- underlineShape = GXGetGlyphUnderlines(theShape);
-
- } else {
-
- shapeCopy = GXCopyToShape(nil, theShape);
- nrequire(status = GXGetGraphicsError(nil), failed_copy);
-
- if (theType == gxLayoutType)
- GXPrimitiveShape(shapeCopy); // convert it to a glyph shape with layout applied.
- else
- GXSetShapeType(shapeCopy, gxGlyphType); // was a text shape, make it a glyph shape.
-
- #if DEBUGLEVEL > 1
- theType = GXGetShapeType(shapeCopy);
- if (theType != gxGlyphType)
- dprintf(trace, "Fatal Error, primitiveShape did not make glyph from layout");
- #endif
-
- underlineShape = GXGetGlyphUnderlines(shapeCopy);
- GXDisposeShape(shapeCopy);
-
- }//end if
-
- /* Make the original shape a picture and add the underline shape to it. */
-
- GXSetShapeType(theShape, gxPictureType);
- GXSetPictureParts(theShape, 0, 0, 1, &underlineShape, nil, nil, nil);
-
- #ifdef noBugs
- GXDisposeShape(underlineShape);
- #endif
-
- status = GXGetGraphicsError(nil);
- ncheck(status);
-
- }//end if
-
- failed_copy:
- failed_notText:
-
- return(status);
-
- }//SeperateUnderlineShape
-
- #endif
-